package cycles.util.date;
import static cycles.util.date.CNElement.EARTH;
import static cycles.util.date.CNElement.FIRE;
import static cycles.util.date.CNElement.METAL;
import static cycles.util.date.CNElement.WATER;
import static cycles.util.date.CNElement.WOOD;
import static cycles.util.date.CNElement.getEle;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CNEra {
	
	
	
	private static char[] GAN = { '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛',
			'壬', '癸', };
	private static final int[] GAN_5X = {

	WATER, WOOD, WOOD, FIRE, FIRE, EARTH, EARTH, METAL, METAL, WATER, WATER };
	private static char[] ZHI = { '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未',
			'申', '酉', '戌', '亥', };
	private static final int[] ZHI_5X = { WATER, WATER, EARTH, WOOD, WOOD,
			EARTH, FIRE, FIRE, EARTH, METAL, METAL, EARTH, WATER };

	private static final int[] MONTH_ADJUST = { 0, 1, 2, 0, 1, 1, 2, 2, 3, 4,
			4, 5, 5 };

	public CNEra(int year, int month, int day, int hour, int min) {
		if (hour == 23) {
			// 23:00-00:00，应该是第二天的时间，所以年月日要重新算一下
			month = month - 1;
			Calendar cal = Calendar.getInstance();
			cal.set(year, month, day);
			cal.add(Calendar.DAY_OF_YEAR, 1);
			year = cal.get(Calendar.YEAR);
			month = cal.get(Calendar.MONTH);
			day = cal.get(Calendar.DAY_OF_MONTH);
			month = month + 1;
		}
		System.out.println("农历:"+year + "-" + month + "-" + day);

		int ylast3 = year - 1900;

		int para = (ylast3 * 5 + ylast3 / 4 + 9 + day + ((month & 0x01) == 0 ? 30
				: 0))
				+ MONTH_ADJUST[month];
		if (month == 1 || month == 2) {
			// 闰年的1,2月要减1
			if ((year & 0x3) == 0) {
				if (year % 100 == 0) {
					if (((year / 100) & 0x3) == 0)
						para = para - 1;
				} else {
					para = para - 1;
				}

			}

		}
		this.day_gan = para % 10;
		this.day_zhi = para % 12;

		try {
			CNCalendar cncal = new CNCalendar(year, month, day);
			year = cncal.getChineseYear();
			year = year - 2697;
			month = cncal.getChineseMonth();
			if (month < 0) {
				this.isLeap = true;
				month = -month;
			}
			day = cncal.getChineseDay();
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println(year + "-" + month + "-" + day);

		year = (year - 3) % 60;
		this.year_gan = year % 10;
		this.year_zhi = year % 12;
		this.month_gan = ((year_gan * 2) + month) % 10;
		this.month_zhi = (month + 2) % 12;

		this.hour_zhi = ((hour + 3) / 2) % 12;
		this.hour_gan = (day_gan * 2 + hour_zhi - 2) % 10;
	}

	public List<CNElement> lack() {
		Set<Integer> has = new HashSet<Integer>();
		has.add(GAN_5X[this.year_gan]);
		has.add(ZHI_5X[this.year_zhi]);
		has.add(GAN_5X[this.month_gan]);
		has.add(ZHI_5X[this.month_zhi]);
		has.add(GAN_5X[this.day_gan]);
		has.add(ZHI_5X[this.day_zhi]);
		has.add(GAN_5X[this.hour_gan]);
		has.add(ZHI_5X[this.hour_zhi]);
		System.out.println(has.size());
		List<CNElement> ret = new ArrayList<CNElement>();
		if (!has.contains(WATER)) {
			ret.add(getEle(WATER));
		}
		if (!has.contains(METAL)) {
			ret.add(getEle(METAL));
		}
		if (!has.contains(WOOD)) {
			ret.add(getEle(WOOD));
		}
		if (!has.contains(FIRE)) {
			ret.add(getEle(FIRE));
		}
		if (!has.contains(EARTH)) {
			ret.add(getEle(EARTH));
		}
		return ret;
	}

	public CNElement get5X() {
		return getEle(GAN_5X[this.day_gan]);

	}

	public CNElement getDayGan() {
		return getEle(GAN_5X[this.day_gan]);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();

		sb.append(GAN[year_gan]);
		sb.append(ZHI[year_zhi]);
		sb.append("年");
		if (this.isLeap) {
			sb.append("闰");
		}
		sb.append(GAN[month_gan]);
		sb.append(ZHI[month_zhi]);
		sb.append("月");
		sb.append(GAN[day_gan]);
		sb.append(ZHI[day_zhi]);
		sb.append("日");
		sb.append(GAN[hour_gan]);
		sb.append(ZHI[hour_zhi]);
		sb.append("时");
		sb.append("命属" + getDayGan().getCntext());
		sb.append("，");
		List<CNElement> eles = this.lack();
		if (eles.size() == 0) {
			sb.append("五行不缺");
		} else {
			sb.append("五行缺");
			for (CNElement ele : eles) {
				sb.append(ele.getCntext());
				sb.append(",");
			}
		}
		return sb.toString();
	}

	int year_gan;
	int year_zhi;
	int month_gan;
	int month_zhi;
	int day_gan;
	int day_zhi;
	int hour_gan;
	int hour_zhi;

	boolean isLeap = false;

	public static void main(String[] args) {
		// GanZhiTime time = new GanZhiTime(1980, 4, 3, 7, 30);
		CNEra time = new CNEra(2012, 1, 10, 14, 31);

		System.out.println(time);
	}
}
